package com.ms.game.db.dto;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ms.game.common.container.LevelInfoBinUtil;
import com.ms.game.db.util.Utility;
import com.ms.game.itembox.ItemField;
import com.ms.player.Player;
import com.ms.player.PlayerNickNameParser;
import com.ms.service.module.account.Account;
import com.ms.service.module.account.db.AccountModel;
import com.ms.service.module.zone.message.SSimplePlayer;
import com.xpec.c4.db.dao.PlayerLevelCalculator;
import com.xpec.c4.db.model.PlayerModel;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.game.utility.GameUtility;

/**
 * 數據轉換傳輸類
 * 
 * model <=> class
 * 
 * @author Bany
 * 
 */
public class DataTransfer {
	
	
	private static final Log log = LogFactory.getLog(DataTransfer.class);
	
	/**
	 * VO、PO互換
	 * @param <T>
	 * 
	 * @param orig
	 * @param dest
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T transfer(Object orig, T dest) {
		if (orig != null) {
			if (dest == null
					|| !Utility.mapingClass(orig.getClass()).equals(
							dest.getClass())) {
				throw new IllegalArgumentException();
			}
		}
		return (T) Utility.copyProperties(orig, dest);
	}

	/**
	 * 根據VO生成PO
	 * 
	 * @param orig
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T transfer(Object orig) {
		Object dest = Utility.mappingObject(orig);
		return (T) Utility.copyProperties(orig, dest);
		// return dest;
	}
	
	/**
	 * 根据账户的VO生成PO
	 * 
	 * @param account
	 *            账户VO
	 * @param accountModel
	 *            账户PO
	 * @return
	 */
	public static AccountModel transfer(Account account,
			AccountModel accountModel) {
		if (account == null) {
			return null;
		}
		if (accountModel == null) {
			accountModel = new AccountModel();
		}
		Utility.copyProperties(account, accountModel);

		accountModel.setAccountId(GUID.toString(account.getAccountId()));
		if(account.getPlayers() != null){
			ArrayList<String> list = new ArrayList<String>();
			for(GUID players:account.getPlayers())
				list.add(GUID.toString(players));
			accountModel.setPlayers(list);
		}
		
		if(account.getPlayerSerialNumMap() != null)
		{
			Map<String, Integer> serialNumMap = accountModel.getPlayerSerialNumMap();
			if(serialNumMap == null)
			{
				serialNumMap = new HashMap<String, Integer>();
				accountModel.setPlayerSerialNumMap(serialNumMap);
			}
			for(Entry<GUID, Integer> entry : account.getPlayerSerialNumMap().entrySet())
			{
				serialNumMap.put(GUID.toString(entry.getKey()), entry.getValue());
			}
			
		}
		
		return accountModel;
	}
	
	/**
	 * 根据账户的PO生成VO
	 * 
	 * @param accountModel
	 * @param account
	 * @return
	 */
	public static Account transfer(AccountModel accountModel, Account account) {
		if (accountModel == null) {
			return null;
		}
		if (account == null) {
			account = new Account();
		}
		Utility.copyProperties(accountModel, account);
		account.setAccountId(GUID.parseUUID(accountModel.getAccountId()));
		if(accountModel.getPlayers() != null){
			ArrayList<GUID> list = new ArrayList<GUID>();
			for(String players:accountModel.getPlayers())
				list.add(GUID.parseUUID(players));
			account.setPlayers(list);
		}
		
		if(accountModel.getPlayerSerialNumMap() != null)
		{
			Map<GUID, Integer> serialNumMap = account.getPlayerSerialNumMap();
			if(serialNumMap == null)
			{
				serialNumMap = new HashMap<GUID, Integer>();
				account.setPlayerSerialNumMap(serialNumMap);
			}
			for(Entry<String, Integer> entry : accountModel.getPlayerSerialNumMap().entrySet())
			{
				serialNumMap.put(GUID.parseUUID(entry.getKey()), entry.getValue());
			}
			
		}
		
		return account;

	}

	/**
	 * 根據賬戶的VO生成PO
	 * 
	 * @param account
	 * @return
	 */
	public static AccountModel transfer(Account account) {
		if (account == null) {
			return null;
		}
		try{
			AccountModel accountModel = new AccountModel();
			return transfer(account, accountModel);
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error("AccountModel transfer failed", e);
			}
		}
		return null;
	}

	/**
	 * 根據賬戶的VO生成PO
	 * 
	 * @param account
	 * @return
	 */
	public static List<AccountModel> transferAccounts(List<Account> accounts) {
		List<AccountModel> accountModels = new ArrayList<AccountModel>();
		for (Account account : accounts) {
			accountModels.add(transfer(account));
		}
		return accountModels;
	}
	
	/**
	 * 根據賬戶的PO生成VO
	 * 
	 * @param accountModel
	 * @return
	 */
	public static Account transfer(AccountModel accountModel) {
		if (accountModel == null) {
			return null;
		}
		
		try{
			Account account = new Account();
			return transfer(accountModel, account);
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error("Account transfer failed", e);
			}
		}
		return null;
	}

	public static List<Account> transferAccountModels(
			List<AccountModel> accountModels) {
		List<Account> accounts = new ArrayList<Account>();
		for (AccountModel accountModel : accountModels) {
			accounts.add(transfer(accountModel));
		}
		return accounts;
	}
	
	/**
	 * List<Player>轉List<PlayerModel>
	 * 
	 * @param players
	 * @param playerModles
	 * @return
	 */
	public static List<PlayerModel> transferPlayers(List<Player> players) {
		if (players == null) {
			return null;
		}
		List<PlayerModel> playerModles = new ArrayList<PlayerModel>();
		for (Player player : players) {
			playerModles.add(playerToModel(player, null));
		}
		// transferPlayers(players, playerModles);
		return playerModles;
	}
	
	/**
	 * 將 player 轉成 player model
	 * 
	 * @param player
	 *            要轉換的 player 資料
	 * @param model
	 *            如果是新建角色就給 null，如果是已存在角色要更新資料就填入角色的 model
	 * @return
	 * @see com.ms.player.Player
	 * @see com.xpec.c4.db.model.PlayerModel
	 */
	public static PlayerModel playerToModel(Player player, PlayerModel model) {
		if (player == null) {
			return null;
		}
		
		PlayerModel playermodle = null;
		if(model!=null){
			playermodle = model;
		}else{
			playermodle = new PlayerModel();
		}
		
		try{
			playermodle = transfer(player, playermodle);
			
			playermodle.setGuid(player.getGuid().toString());
			playermodle.setAccountId(player.getAccountId().toString());
			playermodle.setLoginTime(GameUtility.longToDate(player.getLoginTime()));
			playermodle.setCreateTime(GameUtility.longToDate(player.getCreateTime()));			
			playermodle.setMonthlyFeeEndTime(GameUtility.longToDate(player.getMonthlyFeeEndTime()));
			playermodle.setMonthlyAwardTime(GameUtility.longToDate(player.getMonthlyAwardTime()));
			playermodle.setWeeklyFeeEndTime(GameUtility.longToDate(player.getWeeklyFeeEndTime()));
			playermodle.setWeeklyAwardTime(GameUtility.longToDate(player.getWeeklyAwardTime()));
			playermodle.setBanTalkTime(player.getBanTalkTime());
			if (player.getNameModifyTime() == 0) {
				// 沒有值
				playermodle.setNameModifyTime(null);
			} else {
				// 有值
				playermodle.setNameModifyTime(GameUtility.longToDate(player.getNameModifyTime()));
			}
			
			if (player.getLastloginTime() != 0) {
				playermodle.setLastloginTime(GameUtility.longToDate(player.getLastloginTime()));
			} else {
				playermodle.setLastloginTime(GameUtility.longToDate(0));
			}
		
			playermodle.setRegisteredPlatform(player.getRegisteredPlatform());
			
			playermodle.setCanMakeCommission(player.isCanMakeCommission());
			
			playermodle.setPlayerIdentityType(player.getPlayerIdentityType());
			
			return playermodle;
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error("PlayerModel transfer failed:", e);
			}
		}
		return null;
	}
	
	/**
	 * List<PlayerModel>轉List<Player>
	 * 
	 * @param playerModels
	 * @return
	 */
	public static List<Player> transferPlayerModels(
			List<PlayerModel> playerModels) {
		if (playerModels == null) {
			return null;
		}
		List<Player> players = new ArrayList<Player>();
		for (PlayerModel playerModle : playerModels) {
			players.add(transfer(playerModle));
		}
		return players;
	}
	
	/**
	 * 根據PO生成VO
	 * 
	 * @param playerModel
	 * @return
	 */
	public static Player transfer(PlayerModel playerModel) {		
		if (playerModel == null) {
			return null;
		}
		
		Player player = new Player();

		try{
			player =  transfer(playerModel, player);
			
			player.setGuid(GUID.parseUUID(playerModel.getGuid()));
			player.setAccountId(GUID.parseUUID(playerModel.getAccountId()));
			player.setLoginTime(playerModel.getLoginTime().getTime());
			player.setCreateTime(playerModel.getCreateTime().getTime());			
			player.setBanTalkTime(playerModel.getBanTalkTime());
			
			player.setCanMakeCommission(playerModel.isCanMakeCommission());
			
			player.setPlayerIdentityType(playerModel.getPlayerIdentityType());
			
			if(playerModel.getMonthlyAwardTime() != null){
				player.setMonthlyAwardTime(playerModel.getMonthlyAwardTime().getTime());
			}
			if(playerModel.getMonthlyFeeEndTime() != null){
				player.setMonthlyFeeEndTime(playerModel.getMonthlyFeeEndTime().getTime());
			}

			if(playerModel.getWeeklyAwardTime() != null){
				player.setWeeklyAwardTime(playerModel.getWeeklyAwardTime().getTime());
			}
			if(playerModel.getWeeklyFeeEndTime() != null){
				player.setWeeklyFeeEndTime(playerModel.getWeeklyFeeEndTime().getTime());
			}
			
			if(playerModel.getLogoutTime() != null){
				player.setLogoutTime(playerModel.getLogoutTime().getTime());
			}
			
			if (playerModel.getNameModifyTime() == null) {
				// 沒有值
				player.setNameModifyTime(0);
			} else {
				// 有值
				player.setNameModifyTime(playerModel.getNameModifyTime().getTime());
			}
			
			if (playerModel.getLastloginTime() != null){
				player.setLastloginTime(playerModel.getLastloginTime().getTime());
			}
			else {
				player.setLastloginTime(0);
			}
			
			return player;
		}catch(Exception e){
			if(log.isErrorEnabled()){
				log.error("Player transfer failed:", e);
			}
		}
		return null;
	}
	
	/**
	 * 角色資料轉成傳給 client 的格式
	 * 
	 * @param player
	 *            角色資料
	 * @return 回傳給 client 的角色資料格式
	 */
	public static SSimplePlayer PlayerToSimple(Player player) {
		if (player == null) {
			return null;
		}

		SSimplePlayer sp = new SSimplePlayer();

		/** 自身id */
		sp.setGuid(player.getGuid());
		
		/** 字串guid */
		sp.setStr_guid(player.getGuid().toString());

		/** 帳戶id */
		sp.setAccountId(player.getAccountId());

		/** 名稱 */
//		sp.setName(player.getName());
		sp.setName(PlayerNickNameParser.mergeNickName(player.getName(), player.getNameNumber()));
		
		/** 性別 */
		sp.setGender(player.isGender());

		/** 等级 */
		sp.setLevel(player.getLevel());
		
		/** 經驗值*/
		sp.setExp(player.getExp().toString());
		
		/** 當前等級經驗值, 下一級需求經驗值 */
		HashMap<String, Long> expInfos = LevelInfoBinUtil.getExpInfos(player.getExp());
		sp.setExpCurrentLevel(expInfos.get(PlayerLevelCalculator.EXP_IN_CURRENT_LEVEL).toString());
		sp.setExpToNextLevel(expInfos.get(PlayerLevelCalculator.EXP_TO_NEXT_LEVEL).toString());
		
		/** 金幣 */
		sp.setGoldCoin(player.getGoldCoin().toString());

		/** 試玩幣 */
		sp.setTrialCoin(player.getTrialCoin().toString());

		/** 幸運金 */
		sp.setLuckyCoin(player.getLuckyCoin().toString());

		/** 所在的 zone id */
		sp.setZoneId(player.getZoneId());

		/** 角色名稱被修改的時間 */
		sp.setNameModifyTime(player.getNameModifyTime());

		/** 頭像 */
		sp.setFacephoto(player.getFacephoto());

		/** 是否為試玩帳號 */
		sp.setTrialAccount(player.isTrialAccount());


		/** 是否認證  */
		sp.setVerifiedMember(player.isVerifiedMember());

		/** 是否有邀請碼 */
		sp.setUseInviteCode((GameUtility.isHaveString(player.getUplineCode())) ? true : false);
		
		/** VIP等級 */
		sp.setVip(player.getVip());
		
		/** VIP經驗 */
		sp.setVipExp(player.getVipExp());

		// TODO kevin item 完成後刪掉這一項
		/** 道具箱 */
		sp.setItemFields(new ArrayList<ItemField>());

		/** 禁言效果過期時間 */
		sp.setSilentExpireTime(player.getSilentExpireTime());

		/** 後台禁言時間*/
		sp.setBanTalkTime(player.getBanTalkTime() == -1 ? -1 : player.getBanTalkTime() * 1000);
		
		/** 自己的邀請碼 */
		sp.setInviteCode(player.getInviteCode());

		/** 連續登入天數 */
		sp.setContinuousLoginCount(player.getContinuousLoginCount());
		
		/** 水晶 */
		sp.setCrystal(player.getCrystal());
		
		/**角色名稱隨機碼*/
//		sp.setNameNumber(player.getNameNumber());

		return sp;
	}
}
